package lc;

import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;

/**
 * 测试forname与loadclass区别
 * forname经过链接和初始化，直接执行static代码块
 * loadclass不经过链接与初始化，初次实例化时执行static代码块
 * https://www.cnblogs.com/silyvin/articles/10293512.html
 * Created by sunyuming on 19/1/19.
 */
public class LoadClassForName {
    public static void main(String[] args) throws Exception {
//        A a = new A();
//        System.out.println(1);
//
//        Class CA_1 = Class.forName("lc.A");
//        System.out.println(2);

//        Class CA0 = Thread.currentThread().getContextClassLoader().loadClass("lc.A");
//        Method method = CA0.getMethod("teststatic");
//        method.invoke(null);    // 会触发static代码块
//        CA0.newInstance();    // 也会触发static代码块
//        System.out.println(3);

        String dir = "file:/Users/sunyuming/Documents/tool/jars/MyTest-1.0-SNAPSHOT.jar";
        URL url = new URL(dir);
        URL[] urls2 = {url};
        MyUrlClassLoader myUrlClassLoader = new MyUrlClassLoader(urls2);
        Class CA = myUrlClassLoader.findClass("lc.A");  // findclass不会触发static代码块
     //   Class CA = myUrlClassLoader.loadClass("lc.A");  // loadclass优先在本jar包查找
//        Method method = CA.getMethod("teststatic");
//        method.invoke(null);    // 会触发static代码块
        CA.newInstance();   // 触发static代码块

    }

    private static class MyUrlClassLoader extends URLClassLoader {

        public MyUrlClassLoader(URL[] urls) {
            // 以系统类加载器为父加载器
            super(urls);
        }

        @Override
        protected Class<?> findClass(final String name) throws ClassNotFoundException {
            return super.findClass(name);
        }
    }
}
